/**
 * 备选词的选择控件
 * @file CandidateArea.js
 * @author chuzhenyang(chuzhenyang@baidu.com)
 */

define(function (require) {
    var u = require('underscore');
    var esui = require('esui');
    var lib = require('esui/lib');
    var Control = require('esui/Control');
    var eoo = require('eoo');
    var $ = require('jquery');
    var painters = require('esui/painters');

    /**
     * 备选词的选择控件
     *
     * @extends {Control}
     * @param {Object} options 初始化参数
     * @constructor
     */
    var CandidateArea = eoo.create(
        Control,
        {
            /**
             * 控件类型,始终为`"CandidateArea"`
             *
             * @type {string}
             * @readonly
             * @override
             */
            type: 'CandidateArea',

            /**
             * 初始化参数
             *
             * @param {Object} [options] 构造函数传入的参数
             * @protected
             * @override
             */
            initOptions: function (options) {
                var properties = {
                    /**
                     * @property {number} [width=400]
                     *
                     * 默认宽度
                     */
                    width: 400,
                    /**
                     * @property {number} [width=200]
                     *
                     * 默认高度
                     */
                    height: 200,
                    /**
                     * @property {Array} [datasource=['']]
                     *
                     * 控件的数据源,是一个备选区域备选词汇的数组
                     */
                    datasource: [],
                    /**
                     * @property {boolean} [reset=false]
                     *
                     * 是否允许选中之后再被取消选中,默认是不允许的
                     */
                    reset: false,
                    /**
                     * @property {boolean} [repeat=false]
                     *
                     * 是否允许重复词汇的出现,默认是不允许的
                     */
                    repeat: false,
                    /**
                     * @property {String} [noDataText='无候选词汇']
                     *
                     * 当datasource不存在或者为空时,显示的文案
                     */
                    noDataText: '无候选词汇',
                    /**
                     * @property {String} [noDataText='无候选词汇']
                     *
                     * 被选中的值的集合
                     */
                    selectedValue: []
                };
                u.extend(properties, options);

                if (!options.selectedValue) {
                    properties.selectedValue = [];
                }

                this.setProperties(properties);
            },

            /**
             * 重渲染
             *
             * @method
             * @protected
             * @override
             */
            repaint: painters.createRepaint(
                Control.prototype.repaint,
                /**
                 * @property {Array} datasource
                 * @property {boolean} repeat
                 *
                 * 数据源以及是否允许重复
                 */
                {
                    name: ['datasource', 'repeat'],
                    paint: function (area, datasource, repeat) {
                        if (!datasource || datasource.length === 0) {
                            renderErrorContent.call(area);
                            return;
                        }

                        renderDatasource.call(area);
                        area.setProperties({selectedValue: area.selectedValue});
                    }
                },
                /**
                 * @property {Array} selectedValue
                 *
                 * 已选择的值
                 */
                {
                    name: 'selectedValue',
                    paint: function (area, selectedValue) {
                        var children = $(area.main).children();
                        var selectedClass = area.helper.getPartClassName('option-selected');
                        u.each(children, function (child) {
                            if (u.contains(selectedValue, $(child).data('optionValue'))) {
                                $(child).addClass(selectedClass);
                            }
                            else {
                                $(child).removeClass(selectedClass);
                            }
                        });
                    }
                },
                /**
                 * @property {Number} width
                 * @property {Number} height
                 *
                 * 宽度和高度
                 */
                {
                    name: ['width', 'height'],
                    paint: function (area, width, height) {
                        $(area.main).width(width);
                        $(area.main).height(height);
                    }
                }
            ),

            /**
             * 初始化事件交互
             *
             * @protected
             * @override
             */
            initEvents: function () {
                var selectedClass = this.helper.getPartClassName('option-selected');

                // 为所有备选的文本添加可选择的点击事件
                this.helper.addDOMEvent(
                    this.main,
                    'click',
                    '[data-role-type="option"]',
                    u.bind(function (event) {
                        var selectedNode = $(event.currentTarget);
                        var value = selectedNode.data('optionValue');
                        var selectedValue = this.selectedValue.concat([]);
                        if (!selectedNode.hasClass(selectedClass)) {
                            selectedValue.push(value);
                            this.setProperties({selectedValue: u.uniq(selectedValue)});
                            this.fire('change', {value: value, selected: true});
                        }
                        else if (this.reset) {
                            this.setProperties({selectedValue: u.without(selectedValue, value)});
                            this.fire('change', {value: value, selected: false});
                        }
                    }, this)
                );
            },

            /**
             * 添加一个选中值
             *
             * @protected
             * @param {string} value 要选中的值
             */
            addSelected: function (value) {
                if (u.contains(this.selectedValue, value)) {
                    return;
                }
                var selectedValue = this.selectedValue.concat([]);
                selectedValue.push(value);
                this.setProperties({selectedValue: selectedValue});
            },

            /**
             * 取消一个选中值
             *
             * @protected
             * @param {string} value 要选中的值
             */
            removeSelected: function (value) {
                var index = this.selectedValue.indexOf(value);
                if (index >= 0) {
                    var selectedValue = this.selectedValue.concat([]);
                    selectedValue.splice(index, 1);
                    this.setProperties({selectedValue: selectedValue});
                }
            }
        }
    );

    /**
     * 渲染无数据时的内容
     *
     */
    function renderErrorContent() {
        var errorTpl = '<p class="${errorClass}">${errorText}</p>';
        var helper = this.helper;

        this.main.innerHTML = lib.format(
            errorTpl,
            {
                errorClass: helper.getPartClasses('error'),
                errorText: this.noDataText
            }
        );
    }

    /**
     * 渲染数据源
     *
     */
    function renderDatasource() {
        // 先拷贝一份,去重操作不能改变原有的数据源
        var cloneDatasource = this.datasource.concat([]);
        if (!this.repeat) {
            cloneDatasource = u.uniq(cloneDatasource);
        }

        // 需要将其HTML清空
        this.main.innerHTML = '';

        var singleTextTpl = [
            '<div class="${optionClass}" data-role-type="option">',
                '<span class="${optionTextClass}">${optionText}</span>',
            '</div>'
        ].join('');
        var mainElement = $(this.main);
        var helper = this.helper;
        var selectedClass = helper.getPartClassName('option-selected');

        u.each(cloneDatasource, function (source) {
            var addElement = $(lib.format(
                singleTextTpl,
                {
                    optionClass: helper.getPartClasses('option'),
                    optionTextClass: helper.getPartClasses('optionText'),
                    optionText: source
                }
            ));
            // 将datasource的值赋进去
            addElement.data('optionValue', source);
            if (u.contains(this.selectedValue, source)) {
                addElement.addClass(selectedClass);
            }
            else {
                addElement.removeClass(selectedClass);
            }
            mainElement.append(addElement);
        }, this);
    }
    esui.register(CandidateArea);
    return CandidateArea;
});
